#include "Protocol.hpp"
#include "util.hpp"

static bool Usage(char *str)
{
    cerr << "Usage: " << str << " Port (Ip)" << endl;
}

static Response calauator(const Request &req)
{
    Response res;
    switch (req._op)
    {
    case '+':
        res._result = req._x + req._y;
        res._exitCode = 0;
        break;
    case '-':
        res._result = req._x - req._y;
        res._exitCode = 0;
        break;
    case '/':
        if (req._y == 0)
            res._exitCode = -1;
        else
            res._result = req._x / req._y;
        break;
    case '%':
        if (req._y == 0)
            res._exitCode = -2;
        else
            res._result = req._x + req._y;
        break;
    case '*':
        res._result = req._x * req._y;
        res._exitCode = 0;
        break;
    default:
        res._exitCode - 3;
        break;
    }
    return res;
}

struct ThreadData
{
    uint16_t ClientIp
};

void netCal(void *Data)
{
}

class TcpServer
{
public:
    TcpServer(uint16_t port, string ip = "")
        : _port(port), _ip(ip), _listenSock(-1)
    {
    }
    ~TcpServer()
    {
        if (_listenSock > 0)
        {
            close(_listenSock);
        }
    }
    void init()
    {
        _listenSock = socket(AF_INET, SOCK_STREAM, 0);
        if (_listenSock < 0)
        {
            cerr << "socket: " << strerror(errno) << endl;
            exit(2);
        }
        struct sockaddr_in ListenSock;
        bzero(&ListenSock, sizeof ListenSock);
        ListenSock.sin_family = AF_INET;
        ListenSock.sin_port = htons(_port);
        _ip.empty() ? (ListenSock.sin_addr.s_addr = INADDR_ANY) : inet_aton(_ip.c_str(), &ListenSock.sin_addr);
        if (bind(_listenSock, (sockaddr *)&ListenSock, sizeof(ListenSock)) < 0)
            ;
        {
            cerr << "bind: " << strerror(errno) << endl;
            exit(3);
        }
        if (listen(_listenSock, 5) < 0)
        {
            cerr << "listen: " << strerror(errno) << endl;
        }
    }

    void loop()
    {
        while (true)
        {
            struct sockaddr_in ClientSock;
            socklen_t s = 0;
            int Clientfd = accept(_listenSock, (sockaddr *)&ClientSock, &s);
            if (Clientfd < 0)
            {
                cerr << "accept: " << strerror(errno) << endl;
            }
            pthread_t tid;
            pthread_create(&tid, )
        }
    }

private:
    uint16_t _port;
    string _ip;
    int _listenSock;
};

int main(int argc, char *argv[])
{
    if (argc != 2 || argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    return 0;
}